package com.regex.web.controller.gen;


import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.regex.web.cache.DictCacheService;
import com.regex.web.common.excel.ExportExcel;
import com.regex.web.entity.gen.DatabaseDTO;
import com.regex.web.entity.gen.FieldInfoDTO;
import com.regex.web.entity.gen.TableInfoDTO;
import com.regex.web.service.gen.IDatabaseService;
import com.regex.web.service.gen.IFieldInfoService;
import com.regex.web.service.gen.ITableInfoService;
import com.regex.web.utils.AjaxUtil;
import com.regex.web.utils.Contant;
import com.regex.web.utils.QueryResult;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author ocean.ma
 * @since 2019-07-23
 */
@Controller
@RequestMapping("sys/tableInfo")
public class TableInfoController {

	private final static Logger logger = LoggerFactory.getLogger(TableInfoController.class);
	
	@Autowired
	private ITableInfoService ITableInfoService;
	
	@Autowired
	private IDatabaseService IDatabaseService;
	
	@Autowired
	private IFieldInfoService IFieldInfoService;
	
	@Autowired
	private DictCacheService dictService;
	
	/**
	 * 分页查询
	 * @param page
	 * @param model
	 * @param tableInfoDTO
	 * @return
	 */
	@RequestMapping("show")
	public String show(Page<TableInfoDTO> page, Model model,@ModelAttribute("tableInfoDTO") TableInfoDTO tableInfoDTO) {
		try {
			QueryWrapper<TableInfoDTO> param = new QueryWrapper<TableInfoDTO>();
	        QueryResult<TableInfoDTO> result = ITableInfoService.page(page, param);
	        model.addAttribute("result", result);
        } catch (Exception e) {
			e.printStackTrace();
			logger.error("show page is Exception!");
		}
		return "sys/tableInfo/show";
	}
	
	/**
	 * 编辑/新增
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping("input")
    public String toSave(String id, @ModelAttribute("dbId") String dbId, Model model, HttpServletRequest request) {
    	try {
	        if(StringUtils.isNotEmpty(id)) {
	        	TableInfoDTO tableInfoDTO = ITableInfoService.getById(id);
	            model.addAttribute("tableInfoDTO", tableInfoDTO);
	        }
	        
	        DatabaseDTO database = IDatabaseService.getById(dbId);
	        List<TableInfo> tableList = getTableInfo("", database, request);
	        model.addAttribute("tableList", tableList);
        } catch (Exception e) {
			e.printStackTrace();
			logger.error("toSave page is Exception!");
		}
        return "sys/tableInfo/input";
    }
	
	@RequestMapping("getTableFields")
	public String getTableFields(Model model,String tableName, String dbId,HttpServletResponse response, HttpServletRequest request) {
		DatabaseDTO database = IDatabaseService.getById(dbId);
		
		QueryWrapper<TableInfoDTO> queryWrapper = new QueryWrapper<TableInfoDTO>();
		queryWrapper.eq("db_id", dbId);
		queryWrapper.eq("table_name", tableName);
		TableInfoDTO tableInfoDTO = ITableInfoService.getOne(queryWrapper);
		
//		QueryWrapper<FieldInfoDTO> param = new QueryWrapper<FieldInfoDTO>();
//		param.eq("table_id", tableInfoDTO.getId());
//		List<FieldInfoDTO> fields =  IFieldInfoService.list(param);
//		if(fields!= null && fields.size() > 0) {
//			model.addAttribute("fields", fields);
//			model.addAttribute("fieldsStr", JSON.toJSONString(fields));
//		} else {
//		}
		List<TableInfo> tableList = getTableInfo(tableName, database,request);
		for(TableField tableField : tableList.get(0).getFields()) {
			QueryWrapper<FieldInfoDTO> paramOne = new QueryWrapper<FieldInfoDTO>();
			paramOne.eq("table_id", tableInfoDTO.getId());
			paramOne.eq("capital_name", tableField.getCapitalName());
			FieldInfoDTO FieldInfoDTO = IFieldInfoService.getOne(paramOne);
			if(FieldInfoDTO != null) {
				tableField.setComment(FieldInfoDTO.getComment());
				tableField.setPropertyType(FieldInfoDTO.getPropertyType());
				tableField.setHtmlType(FieldInfoDTO.getHtmlType());
				tableField.setDictValue(FieldInfoDTO.getDictValue());
				tableField.setMaxLength(FieldInfoDTO.getMaxLength());
				tableField.setNotNull(FieldInfoDTO.getNotNull());
				tableField.setIsShow(FieldInfoDTO.getIsShow());
				tableField.setIsSelect(FieldInfoDTO.getIsSelect());
			}
		}
		model.addAttribute("fields", tableList.get(0).getFields());
		model.addAttribute("fieldsStr", JSON.toJSONString(tableList.get(0).getFields()));
		
//        AjaxUtil.ajaxJsonSucMessage(response, tableList.get(0));
        return "sys/database/table_set";
	}
	
	
	public List<TableInfo> getTableInfo(String tableName, DatabaseDTO database, HttpServletRequest request) {
		AutoGenerator mpg = new AutoGenerator();
		
		 GlobalConfig gc = new GlobalConfig();
	      gc.setIdType(IdType.ID_WORKER_STR);
		
		DataSourceConfig dsc = new DataSourceConfig();
		
//		LinkedHashMap<String, Object> dictMap = (LinkedHashMap<String, Object>) request.getSession().getAttribute("dictMap");
		LinkedHashMap<String, String> dbTypeMap = dictService.getDictByKey("db_type");// (LinkedHashMap<String, String>) dictMap.get("db_type");
		String dbType = dbTypeMap.get(database.getDbType());
		if("0".equals(database.getDbType())) {
			dsc.setDbType(DbType.MYSQL);
		} else if("1".equals(database.getDbType())) {
			dsc.setDbType(DbType.MARIADB);
		} else if("2".equals(database.getDbType())) {
			dsc.setDbType(DbType.ORACLE);
		} else if("3".equals(database.getDbType())) {
			dsc.setDbType(DbType.DB2);
		} else if("4".equals(database.getDbType())) {
			dsc.setDbType(DbType.SQL_SERVER2005);
		} else if("5".equals(database.getDbType())) {
			dsc.setDbType(DbType.SQL_SERVER);
		}
	      dsc.setTypeConvert(new MySqlTypeConvert() {
	          // 自定义数据库表字段类型转换【可选】
	          public DbColumnType processTypeConvert(String fieldType) {
	              System.out.println("转换类型：" + fieldType);
	              // 注意！！processTypeConvert 存在默认类型转换，如果不是你要的效果请自定义返回、非如下直接返回。
	              return (DbColumnType) super.processTypeConvert(gc, fieldType);
	          }
	      });
	      dsc.setDriverName(database.getDbDriverName());
	      dsc.setUsername(database.getDbUserName());
	      dsc.setPassword(database.getDbPassword());
	      dsc.setUrl(database.getDbHost());
//	      dsc.setUrl("jdbc:mysql://127.0.0.1:3306/huli_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai");
	      mpg.setDataSource(dsc);
	      
	      StrategyConfig strategy = new StrategyConfig();
	      
	      strategy.setTablePrefix(new String[] { "t_" });// 此处可以修改为您的表前缀
	      strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
	      
	      if(StringUtils.isNotEmpty(tableName)) {
	    	  strategy.setInclude(new String[] { tableName });
	      }
	      
	      strategy.setSuperEntityColumns(new String[] { "id", "is_del", "create_time", "update_time" });
	      
	      mpg.setStrategy(strategy);
	      
//	      mpg.execute();
	      ConfigBuilder  config = new ConfigBuilder(new PackageConfig(), dsc, strategy, new TemplateConfig(), gc);
	      List<TableInfo> tableList = mpg.getAllTableInfoList(config);
	      System.out.println(tableList.size());
//	      System.out.println(JSON.toJSONString(tableList));
	      return tableList;
	}
    
    /**
	 * 保存
	 * @param tableInfoDTO
	 * @param response
	 */
    @RequestMapping("save")
	public void save(TableInfoDTO tableInfoDTO, HttpServletResponse response) {
		boolean flag = false;
		try {
			if(StringUtils.isNotEmpty(tableInfoDTO.getId())) {
				tableInfoDTO.setUpdateTime(new Date());
				flag = ITableInfoService.updateById(tableInfoDTO);
			} else {
				tableInfoDTO.setIsDel(Contant.is_del_undelete);
				tableInfoDTO.setUpdateTime(new Date());
				tableInfoDTO.setCreateTime(new Date());
				flag = ITableInfoService.save(tableInfoDTO);
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("save page is Exception!");
		}
		int n = 0;
		if(flag) {
			n = 1;
		}
		AjaxUtil.ajaxJsonSucMessage(response, n);
	}
	
	/**
	 * 详情
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping("detial")
    public String detial(String id, Model model) {
        try {
	        if(StringUtils.isNotEmpty(id)) {
	        	TableInfoDTO tableInfoDTO = ITableInfoService.getById(id);
	            model.addAttribute("tableInfoDTO", tableInfoDTO);
	        }
        } catch (Exception e) {
			e.printStackTrace();
			logger.error("detial page is Exception!");
		}
        return "sys/tableInfo/detial";
    }
	
	/**
	 * 删除
	 * @param id
	 * @param response
	 */
	@RequestMapping("del")
    public void del(String id, HttpServletResponse response) {
        int n = 0;
        try {
	        if(StringUtils.isNotEmpty(id)) {
	        	boolean flag = ITableInfoService.removeById(id);
	        	if(flag) {
	        		n = 1;
	        	}
	        } else {
	        	n = 2;
	        }
        } catch (Exception e) {
			e.printStackTrace();
			logger.error("del page is Exception!");
		}
        AjaxUtil.ajaxJsonSucMessage(response, n);
    }
    
    /**
	 * 导出
	 * @param response
	 * @param tableInfoDTO
	 * @return
	 */
    @RequestMapping(value = "export", method=RequestMethod.POST)
    public String exportFile(HttpServletResponse response, @ModelAttribute("tableInfoDTO") TableInfoDTO tableInfoDTO) {
        try {
            QueryWrapper<TableInfoDTO> param = new QueryWrapper<TableInfoDTO>(tableInfoDTO);
        	
        	String fileName = "数据"+(new Date()).getTime()+".xlsx";
            
            List<TableInfoDTO> datas = ITableInfoService.list(param);
            new ExportExcel("数据", TableInfoDTO.class).setDataList(datas).write(response, fileName).dispose();
            return null; 
        } catch (Exception e) {
        	logger.error("exportFile page is Exception!");
            e.printStackTrace();
        }
        return "redirect:show.htm";
    }
	
}
